package com.um.jdy.common.commons.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.mail.MailUtil;
import com.um.jdy.common.commons.service.EmailService;
import com.um.jdy.common.member.constants.VerificationCodeConstant;
import com.um.jdy.common.member.entity.model.CacheCodeKey;
import com.um.jdy.common.member.entity.model.CodeEmailTemplate;
import com.um.jdy.common.member.enums.CodeKey;
import com.um.jdy.common.member.service.ImageCodeService;
import com.um.jdy.common.member.util.MailAccount;
import com.um.jdy.common.platform.code.LoginCode;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.service.CacheService;
import com.um.springboot.starter.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author 邓南辉
 * 日期 2023/2/4
 * 版权所有 广州优匠科技有限公司
 */
@Service
public class EmailServiceImpl implements EmailService {

    @Autowired
    CacheService cacheService;

    @Autowired
    ImageCodeService imageCodeService;

    /**
     * 发送短信验证码
     *
     * @param prefix
     * @param email
     * @param code
     */
    public void sendCode(CodeKey prefix, String email, String code) {
        if(CodeKey.Signin != prefix && CodeKey.FindPwd != prefix ){
            imageCodeService.checkCode(code);
        }

        sendCode(prefix, email);
    }

    /**
     * 发送短信验证码
     *
     * @param prefix
     * @param email
     */
    public void sendCode(CodeKey prefix, String email) {

        CacheCodeKey cacheCodeKey = new CacheCodeKey(prefix, email);

        Long sendTime = cacheService.getCacheObject(cacheCodeKey.getSendTimeKey());
        Long currentTime = System.currentTimeMillis();
        if (null != sendTime && currentTime - sendTime < VerificationCodeConstant.CODE_INTERVAl_TIME) {
            //修改为如果code还有效时间内并未使用，则可以使用旧code
            String code = cacheService.getCacheObject(cacheCodeKey.getCodeKey());
            if(code != null)
                return;
            else{
                throw new ServiceException(LoginCode.SendCodeRrequently);
            }
        }

        String code = RandomUtil.randomNumbers(6);
        CodeEmailTemplate template = new CodeEmailTemplate(prefix, code);
        MailUtil.send(MailAccount.getInstance(), email, template.getTitle(), template.getContent(), false);

        cacheService.setCacheObject(cacheCodeKey.getCodeKey(), code, 1L, TimeUnit.DAYS);
        cacheService.setCacheObject(cacheCodeKey.getIdentitySendTimeKey(), currentTime, 1L, TimeUnit.DAYS);
        cacheService.setCacheObject(cacheCodeKey.getSendTimeKey(), currentTime, 1L, TimeUnit.MINUTES);

    }

    /**
     * 检查短信验证码
     *
     * @param prefix
     * @param email
     * @param emailCode
     * @return
     */
    public boolean checkCode(CodeKey prefix, String email, String emailCode) {
        CacheCodeKey cacheCodeKey = new CacheCodeKey(prefix, email);

        String cacheCode = cacheService.getCacheObject(cacheCodeKey.getCodeKey());
        if (null == cacheCode) {
            throw new ServiceException(LoginCode.CodeMissing);
        }
        if (!StringUtil.equals(emailCode, cacheCode)) {
            throw new ServiceException(LoginCode.CodeError);
        }
        Long identitySendTime = cacheService.getCacheObject(cacheCodeKey.getIdentitySendTimeKey());
        if (System.currentTimeMillis() - identitySendTime > VerificationCodeConstant.CODE_EFFTIVE_TIME) {
            throw new ServiceException(LoginCode.CodeExpired);
        }

        return true;
    }

    /**
     * 废弃验证码
     * @param prefix
     * @param email
     */
    public void expireCode(CodeKey prefix, String email) {
        CacheCodeKey cacheCodeKey = new CacheCodeKey(prefix, email);

        cacheService.deleteObject(cacheCodeKey.getIdentitySendTimeKey());
        cacheService.deleteObject(cacheCodeKey.getCodeKey());
    }
}
